package com.cx.base.day19_thread;

import lombok.extern.slf4j.Slf4j;

import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.RecursiveTask;

/**
 * 在JDK中，提供了这样一种功能：它能够将复杂的逻辑拆分成一个个简单的逻辑来并行执行，
 * 待每个并行执行的逻辑执行完成后，再将各个结果进行汇总，得出最终的结果数据。
 * 有点像Hadoop中的MapReduce。 ForkJoin是由JDK1.7之后提供的多线程并发处理框架。
 * ForkJoin框架的基本思想是分而治之。什么是分而治之？分而治之就是将一个复杂的计算，
 * 按照设定的阈值分解成多个计算，然后将各个计算结果进行汇总。
 * 相应的，ForkJoin将复杂的计算当做一个任务，而分解的多个计算则是当做一个个子任务来并行执行。
 *
 * @Author: robert.song
 * @Date: Created in 2021/11/29
 */
public class Thread_17_1_ForkJoin {
    public static void main(String[] args) {
        ForkJoinPool pool = new ForkJoinPool(5);
//        日志打印的线程可能只有一两个，因此线程到底用多少个取决于机器的空闲程度
        System.out.println(pool.invoke(new MyTask(10)));
    }
}

@Slf4j
class MyTask extends RecursiveTask<Integer> {
    private int n;

    public MyTask(int n) {
        this.n = n;
    }

    @Override
    protected Integer compute() {
        log.info("thread: " + Thread.currentThread().getName());
        log.info("n: " + n);
//        终止条件
        if (n == 1) {
            log.info("the bottom");
            return 1;
        }
        MyTask task = new MyTask(n - 1);
        log.info("fork new thread exec compute()");
        task.fork(); // 让一个线程去执行此任务
        log.info("join new thread result");
        int result = n + task.join(); // 获取任务结果
        return result;
    }
}
